package com.example.battle.handler;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.battle.entity.sys.Battleing;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

/**
 * 处理类：Handler--建立连接，发送消息，关闭连接自动执行
 * @author 01
 *
 */
@Slf4j
public class MyHandler extends TextWebSocketHandler{

    @Autowired
    Match match;

    private static final Map<String, WebSocketSession> users;  //Map来存储WebSocketSession，key用USER_ID 即在线用户列表
    //用户标识
    private static final String USER_ID = "clientId";   //对应监听器从的key
    static {
        users =  new HashMap<String, WebSocketSession>();
    }
    public MyHandler() {}
    /**
     * 连接成功时候，会触发页面上onopen方法
     */
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String userId = (String) session.getAttributes().get(USER_ID);
        log.info(session.getAttributes().get(USER_ID) + "成功建立websocket连接!");
        users.put(userId,session);
        sendMessageToUser(userId, new TextMessage(userId));
        log.info("当前线上用户数量:"+users.size());
        //这块会实现自己业务，比如，当用户登录后，会把离线消息推送给用户
        //TextMessage returnMessage = new TextMessage("成功建立socket连接，你将收到的离线");
        //session.sendMessage(returnMessage);
    }
    /**
     * 关闭连接时触发
     */
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        String userId= (String) session.getAttributes().get(USER_ID);
        match.getMap().remove(userId);
        match.removeMatched(userId);
        match.getMapMatched().remove(userId);
        log.info("用户"+userId+"已退出！");
        // match.removeUser(userId);
        users.remove(userId);
        log.info("剩余在线用户"+users.size());
    }

    /**
     * js调用websocket.send时候，会调用该方法
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        super.handleTextMessage(session, message);
        /**
         * 收到消息，自定义处理机制，实现业务
         */
        log.info("服务器收到"+(String) session.getAttributes().get(USER_ID)+"消息："+message.getPayload());
        //将JsonObject数据转换为Json
        JSONObject object = JSON.parseObject(message.getPayload());
        //利用键值对的方式获取到值
        // log.info((String) object.get("type"));
        String userId = (String) session.getAttributes().get(USER_ID);
        if(object.get("type").equals("connect")){
            // 连接
            if(object.get("way") != null && object.get("way").equals("friend")){
                AccountMessage accountMessage = new AccountMessage();
                accountMessage.set(userId, (String)object.get("avatarUrl"));
                match.getMapFriend().put(userId, accountMessage);
                return;
            }
            String avatarUrl = (String)object.get("avatarUrl");
            AccountMessage accountMessage = new AccountMessage();
            accountMessage.set(userId, avatarUrl);
            match.getMap().put(userId, accountMessage);
        }else if(object.get("type").equals("match")){
            // 匹配
            if(object.get("way") != null && object.get("way").equals("friend")){
                // 好友对战
                String friendAvatarUrl = (String) object.get("friendAvatarUrl");
                String friendNickname = (String) object.get("friendNickname");
                if(match.findFriend(friendAvatarUrl) != null){
                    String id = match.findFriend(friendAvatarUrl);
                    match.getMapMatched().put(userId, id);
                    return;
                }
                return;
            }
            if(match.getMapMatched().get(userId) != null){
                String opponent = match.getMapMatched().get(userId);
                AccountMessage accountMessage = new AccountMessage();
                accountMessage.set(opponent, match.getMap().get(opponent).getAvatarUrl());
                String json = JSON.toJSONString(accountMessage);
                sendMessageToUser(userId, new TextMessage(json));
            }else if(match.findOpponment(userId) != null) {
                String opponent = match.findOpponment(userId);
                match.getMapMatched().put(userId, opponent);
                // log.info(match.getMap().get(opponent));
                /*AccountMessage accountMessage2 = new AccountMessage(userId, match.getMap().get(userId));
                String json2 = JSON.toJSONString(accountMessage2);
                sendMessageToUser(opponent, new TextMessage(json2));*/
            }
        }else if(object.get("type").equals("answer")){
            // 对战
            /*String opponent1 = match.getMapMatched().get(userId);
            match.removeUser(userId);
            match.removeUser(opponent1);*/
            String opponent = match.findMatched(userId);
            if(match.getMap().get(userId) != null){
                match.removeUser(userId,opponent);
            }
            String answer = (String) object.get("answer");
            String score = (String) object.get("score");
            Battleing battleing = new Battleing(answer, score);
            // String opponent = match.findMatched(userId);
            String json = JSON.toJSONString(battleing);
            sendMessageToUser(opponent,new TextMessage(json));
        }else if(object.get("type").equals("finish")){
            // 游戏结束
            String opponent = match.findMatched(userId);
            match.getMapMatched().remove(userId);
            match.getMapMatched().remove(opponent);
        }
        /*if(message.getPayload().startsWith("#match#")){ //开始匹配
            // sendMessageToUser((String)session.getAttributes().get(USER_ID), new TextMessage("服务器单发：" +message.getPayload()));
        }else if(message.getPayload().startsWith("#matched#")){
            match.addMatched(userId,match.find(userId));
            log.info(userId+"匹配"+match.find(userId));
            // sendMessageToUsers(new TextMessage("服务器群发：" +message.getPayload()));
        }else if(message.getPayload().startsWith("#answer#")){
            log.info(message.getPayload());
        }else {
        }*/
    }

    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        if(session.isOpen()){
            session.close();
        }
        log.warn("传输出现异常，关闭websocket连接... ");
        String userId= (String) session.getAttributes().get(USER_ID);
        users.remove(userId);
    }

    public boolean supportsPartialMessages() {
        return false;
    }
    /**
     * 给某个用户发送消息
     *
     * @param userId
     * @param message
     */
    public void sendMessageToUser(String userId, TextMessage message) {
        for (String id : users.keySet()) {
            if (id.equals(userId)) {
                try {
                    if (users.get(id).isOpen()) {
                        users.get(id).sendMessage(message);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
            }
        }
    }

    /**
     * 给所有在线用户发送消息
     *
     * @param message
     */
    public void sendMessageToUsers(TextMessage message) {
        for (String userId : users.keySet()) {
            try {
                if (users.get(userId).isOpen()) {
                    users.get(userId).sendMessage(message);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
